unit uGlobal;

interface

uses
  Types, Classes;

type

  TSystemCfg = class
    BoReadOkNetConfig: Boolean;
    ApiUrl: string;
    HomePage: string;
    QuickPlaceOrderUrl: string;
    FTP_OuterHost: string;
    FTP_OuterPort: Integer;
    FTP_OuterUserName: string;
    FTP_OuterPassword: string;
    FTP_OuterDir: string;
    HttpDocServer: string;
    SrcLanguage: string;
    TarLanguage: string;

    DownloadPath: string;
    CustomDownloadPath: string;
    AutoDownload: Boolean;
    SelectOrdernameToDir: Boolean;
    procedure ReadFromFile;
    procedure WriteToFile;
  end;

function SystemCfg: TSystemCfg;
function URLEncode(const s: WideString): string;
function UrlDecode(s: AnsiString): WideString;
function GetFileSizeEx(const FileName:string):DWORD;
function GetDocTypeDesc(const docName: string): string;
function GetDocTypeValue(const docName: string): string;
procedure FillDocTypeDesc(sl: TStrings);
function FileCanUpload(const AfName: string): Boolean;
function ForceCreateFile(const FileName: string): Boolean;
function GetCurIPAddress: string;
procedure BroadcastUpdateUi;
function EncryptPwd(const APwd: string): string;
function DecryptPwd(const APwd: string): string;

procedure SetV(const Section, Key, value:string);
function GetV(const Section, Key:string): string;

var
  g_SetupIniFile: string;
  g_DocTypes: TStringList;
  g_FavoriteUrls: TStringList;
  g_PendingOrder: TStringList;
  g_OrderIdx: Integer;
  g_MainFormHandle: THandle;
  AppPath: string;

const
  TqVersion = '1.9.22.239';
implementation

uses
  iniFiles, SysUtils, Windows, Forms, Winsock, StrUtils, MainFrm, DESCrypt;

const
  _URL_NORMAL_CHARS = [
    'A'..'Z', 'a'..'z', '0'..'9',
    '$', '-', '_', '.', '+', '!', '*', '''', '(', ')', ','
      ];
  KEY_TEXT = 'Japhe 2009.3.30';

var
  _SystemCfg: TSystemCfg=nil;

function SystemCfg: TSystemCfg;
begin
  if _SystemCfg=nil then
    _SystemCfg := TSystemCfg.Create;
  result := _SystemCfg;
end;

procedure BroadcastUpdateUi;
begin
  if Assigned(MainForm) then
    MainForm.UpdateUi;
end;

{ TSystemCfg }

procedure TSystemCfg.ReadFromFile;
var
  setupIni: TIniFile;
begin
  setupIni := TIniFile.Create(g_SetupIniFile);
  BoReadOkNetConfig := False;
  ApiUrl := setupIni.ReadString('Url', 'ApiUrl', 'http://testtpm1.transn.net/index.php');
  QuickPlaceOrderUrl := setupIni.ReadString('Url', 'QuickPlaceOrderUrl', 'http://testtpm1.transn.net/index.php');
  SrcLanguage := setupIni.ReadString('Url', 'SrcLanguage', '');
  TarLanguage := setupIni.ReadString('Url', 'SrcLanguage', '');

  DownloadPath := setupIni.ReadString('DownloadOrder', 'DownloadPath', '');
  CustomDownloadPath := setupIni.ReadString('DownloadOrder', 'CustomDownloadPath', '');
  AutoDownload := setupIni.ReadBool('DownloadOrder', 'AutoDownload', False);
  SelectOrdernameToDir := setupIni.ReadBool('DownloadOrder', 'SelectOrdernameToDir', False);

  setupIni.Free;
end;

procedure TSystemCfg.WriteToFile;
var
  setupIni: TIniFile;
begin
  setupIni := TIniFile.Create(g_SetupIniFile);

  setupIni.WriteString('DownloadOrder', 'DownloadPath', DownloadPath);
  setupIni.WriteString('DownloadOrder', 'CustomDownloadPath', CustomDownloadPath);
  setupIni.WriteBool('DownloadOrder', 'AutoDownload', AutoDownload);
  setupIni.WriteBool('DownloadOrder', 'SelectOrdernameToDir', SelectOrdernameToDir);

  setupIni.Free;
end;

function URLEncode(const s : WideString) : string;
var
  i, len : integer;
  str:string;
begin
  result := '';
  str := UTF8Encode(s);
  len := length(str);
  for i := 1 to len do
  begin
    if ( str[i] in _URL_NORMAL_CHARS ) then
    begin
      result := result + str[i];
    end
    else
    begin
      result := result + '%' + IntToHex( ord( str[i] ), 2 );
    end;
  end;
end;

function UrlDecode(s: AnsiString): WideString;
var
  a: word;
  ss: string;
begin
  for a:=length(s) downto 1 do
  begin
    if s[a]='%' then
    begin
      Byte(s[a]) := StrToIntDef('$' + copy(s,a+1,2), 0);
      delete(s,a+1,2);
    end
    else if s[a]='+' then
    begin
      s[a]:=' ';
    end;
  end;
  ss :='';
  urldecode := UTF8ToWideString(s + ss);
end;

function GetFileSizeEx(const FileName:string):DWORD;
var
  sr: TSearchRec;
begin
  if FindFirst(FileName, faAnyFile, sr) = 0 then
    Result := sr.Size
  else
    Result := 0;
  SysUtils.FindClose(sr);
end;

function GetDocTypeDesc(const docName: string): string;
var
  i: Integer;
begin
  Result := '';
  for i := 0 to g_DocTypes.Count - 1 do
  begin
    if Pos(g_DocTypes.Names[i], docName)=1 then
    begin
      result := g_DocTypes.ValueFromIndex[i];
      if Pos('|', Result)>0  then
        result := Copy(result, 1, Pos('|', Result)-1);
      break;
    end;
  end;
end;

function GetDocTypeValue(const docName: string): string;
var
  i: Integer;
begin
  Result := '';
  for i := 0 to g_DocTypes.Count - 1 do
  begin
    if Pos(g_DocTypes.Names[i], docName)=1 then
    begin
      result := g_DocTypes.ValueFromIndex[i];
      if Pos('|', Result)>0  then
        result := Copy(result, Pos('|', Result)+1, Length(Result)-Pos('|', Result));
      break;
    end;
  end;
end;

procedure FillDocTypeDesc(sl: TStrings);
var
  i: Integer;
  str: string;
begin
  for i := 0 to g_DocTypes.Count - 1 do
  begin
    str := g_DocTypes.ValueFromIndex[i];
    if Pos('|', str)>0  then
      sl.Add(Copy(str, 1, Pos('|', str)-1));
  end;
end;

function FileCanUpload(const AfName: string): Boolean;
var
  HFileRes: HFILE;
  Attributes, NewAttributes: WORD;
begin
  Result := False;
  if not FileExists(AfName) then
    Exit;
  Attributes := GetFileAttributesW(PWideChar(AfName));
  if (Attributes and faReadOnly) = faReadOnly then
  begin
    NewAttributes := Attributes and not faReadOnly;
    SetFileAttributesW(PWideChar(AfName), NewAttributes);
    Result := True;
    Exit;
  end;

  HFileRes := CreateFileW(PWideChar(AfName), GENERIC_READ or GENERIC_WRITE, 0, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  Result := (HFileRes <> INVALID_HANDLE_VALUE);
  if Result then
    CloseHandle(HFileRes);
end;

function ForceCreateFile(const FileName: string): Boolean;
var
  sl: TStringList;
begin
  Result := True;
  if not FileExists(FileName) then
  begin
    sl := TStringList.Create;
    try
      try
        sl.SaveToFile(FileName);
      except
        Result := False;
      end;
    finally
      sl.Free;
    end;
  end;
end;

procedure GetCurIP(Ips:TStrings);
type
  TaPInAddr = Array[0..10] of PInAddr;
  PaPInAddr = ^TaPInAddr;
var
  phe: PHostEnt;
  pptr: PaPInAddr;
  Buffer: Array[0..63] of AnsiChar;
  I: Integer;
  GInitData: TWSAData;
begin
  WSAStartup($101, GInitData);
  Ips.Clear;
  GetHostName(Buffer, SizeOf(Buffer));
  phe := GetHostByName(buffer);
  if phe = nil then Exit;
  pPtr := PaPInAddr(phe^.h_addr_list);
  I := 0;
  while pPtr^[I] <> nil do
  begin
    Ips.Add(inet_ntoa(pptr^[I]^));
    Inc(I);
  end;
  WSACleanup;
end;

function GetCurIPAddress:string;
var
  IPS:TStrings;
  CurComputerIP:string;
begin
  Result := '';
  IPS := TStringList.Create;
  GetCurIP(IPS);
  if IPS.Count = 0 then
  begin
    IPS.Free;
    Exit;
  end;
  CurComputerIP := IPS.Strings[0];
  Result := CurComputerIP;
  IPS.Free;
end;

function EncryptPwd(const APwd: string): string;
begin
  Result := EnCryptStr(APwd, KEY_TEXT);
end;

function DecryptPwd(const APwd: string): string;
begin
  if Trim(APwd)<>'' then
    Result := DeCryptStr(APwd, KEY_TEXT);
end;

procedure SetV(const Section, Key, value:string);
var
  ini: TIniFile;
begin
  if not FileExists(AppPath + '1.dat') then
  begin
    FileClose(FileCreate(AppPath + '1.dat'));
  end;
  ini := TIniFile.Create(AppPath + '1.dat');
  ini.WriteString(Section, Key, value);
  ini.Free;
end;

function GetV(const Section, Key:string): string;
var
  ini: TIniFile;
begin
  ini := TIniFile.Create(AppPath + '1.dat');
  result := ini.ReadString(Section, Key, '');
  ini.Free;
end;

initialization
  g_OrderIdx := 1;
  g_DocTypes := TStringList.Create;
  g_DocTypes.CaseSensitive := False;
  g_FavoriteUrls := TStringList.Create;
  g_PendingOrder := TStringList.Create;
  AppPath := ExtractFilePath(Application.ExeName);

finalization
  g_PendingOrder.Free;
  g_FavoriteUrls.Free;
  g_DocTypes.Free;

end.
